home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / viewkit / VCal / PrintPS.c++ < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  11.2 KB  |  471 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <stdio.h>
  18. #include <unistd.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <malloc.h>
  22. #include "PrintPS.h"
  23. #include "VCal.h"
  24. #include "Entry.h"
  25. #include "Info.h"
  26. #include "Utils.h"
  27. #include "Preferences.h"
  28. #include <Vk/VkHelpAPI.h>
  29. #include <Vk/VkWarningDialog.h>
  30.  
  31. #include <Sgm/PrintBox.h>
  32.  
  33. static int count;
  34. static Arg args[10];
  35.  
  36. //
  37. // PostScript from pcal
  38. //
  39.  
  40. /*
  41.  * pheader - provides the PostScript routines
  42.  */
  43. static const char *pheader[] = {
  44.   "%!",
  45.   "/titlefont /Times-Bold def",
  46.   "/dayfont /Helvetica-Bold def",
  47.   "/month_names [ (January) (February) (March) (April) (May) (June) (July)",
  48.   "\t\t(August) (September) (October) (November) (December) ] def",
  49.   "/prtnum { 3 string cvs show} def",
  50.   "/drawgrid {\t\t% draw calendar boxes",
  51.   "\tdayfont findfont 10 scalefont setfont",
  52.   "\t0 1 6 {",
  53.   "\t\tdup dup 100 mul 40 moveto",
  54.   "\t\t[ (Sunday) (Monday) (Tuesday) (Wednesday) (Thursday) (Friday) (Saturday) ] exch get",
  55.   "\t\t100 center",
  56.   "\t\t100 mul 35 moveto",
  57.   "\t\t1.0 setlinewidth",
  58.   "\t\t0 1 5 {",
  59.   "\t\t\tgsave",
  60.   "\t\t\t100 0 rlineto ",
  61.   "\t\t\t0 -80 rlineto",
  62.   "\t\t\t-100 0 rlineto",
  63.   "\t\t\tclosepath stroke",
  64.   "\t\t\tgrestore",
  65.   "\t\t\t0 -80 rmoveto",
  66.   "\t\t} for",
  67.   "\t} for",
  68.   "} def",
  69.   "/drawnums {\t\t% place day numbers on calendar",
  70.   "\tdayfont findfont 30 scalefont setfont",
  71.   "\t/start startday def",
  72.   "\t/days ndays def",
  73.   "\tstart 100 mul 5 add 10 rmoveto",
  74.   "\t1 1 days {",
  75.   "\t\t/day exch def",
  76.   "\t\tgsave",
  77. #ifndef SATBLK
  78.   "\t\tday start add 7 mod 0 eq",
  79.   "\t\t{",
  80.   "\t\t\tsubmonth 0 eq",
  81.   "\t\t\t{",
  82.   "\t\t\t\t.8 setgray",
  83.   "\t\t\t} if",
  84.   "\t\t} if",
  85. #endif
  86.   "\t\tday start add 7 mod 1 eq",
  87.   "\t\t{",
  88.   "\t\t\tsubmonth 0 eq",
  89.   "\t\t\t{",
  90.   "\t\t\t\t.8 setgray",
  91.   "\t\t\t} if",
  92.   "\t\t} if",
  93.   "\t\tday prtnum",
  94.   "\t\tgrestore",
  95.   "\t\tday start add 7 mod 0 eq",
  96.   "\t\t{",
  97.   "\t\t\tcurrentpoint exch pop 80 sub 5 exch moveto",
  98.   "\t\t}",
  99.   "\t\t{",
  100.   "\t\t\t100 0 rmoveto",
  101.   "\t\t} ifelse",
  102.   "\t} for",
  103.   "} def",
  104.   "/drawfill {\t\t% place fill squares on calendar",
  105.   "\t/start startday def",
  106.   "\t/days ndays def",
  107.   "\t0 35 rmoveto",
  108.   "\t1.0 setlinewidth",
  109.   "\t0 1 start 1 sub {",
  110.   "\t\tgsave",
  111.   "\t\t.9 setgray",
  112.   "\t\t100 0 rlineto ",
  113.   "\t\t0 -80 rlineto",
  114.   "\t\t-100 0 rlineto",
  115.   "\t\tclosepath fill",
  116.   "\t\tgrestore",
  117.   "\t\t100 0 rmoveto",
  118.   "\t} for",
  119.   "\tsubmonth 1 eq",
  120.   "\t{",
  121.   "\t\t/lastday 42 def",
  122.   "\t\t600 -365 moveto",
  123.   "\t}",
  124.   "\t{",
  125.   "\t\t/lastday 40 def",
  126.   "\t\t400 -365 moveto",
  127.   "\t} ifelse",
  128.   "\tlastday -1 ndays start 1 add add",
  129.   "\t{",
  130.   "\t\t/day exch def",
  131.   "\t\tgsave",
  132.   "\t\t.9 setgray",
  133.   "\t\t100 0 rlineto ",
  134.   "\t\t0 -80 rlineto",
  135.   "\t\t-100 0 rlineto",
  136.   "\t\tclosepath fill",
  137.   "\t\tgrestore",
  138.   "\t\tday 7 mod 1 eq",
  139.   "\t\t{",
  140.   "\t\t\t600 -365 80 add moveto",
  141.   "\t\t}",
  142.   "\t\t{",
  143.   "\t\t\t-100 0 rmoveto",
  144.   "\t\t} ifelse",
  145.   "\t} for",
  146.   "} def",
  147.   "/isleap {\t\t% is this a leap year?",
  148.   "\tyear 4 mod 0 eq\t\t% multiple of 4",
  149.   "\tyear 100 mod 0 ne \t% not century",
  150.   "\tyear 1000 mod 0 eq or and\t% unless it's a millenia",
  151.   "} def",
  152.   "/days_month [ 31 28 31 30 31 30 31 31 30 31 30 31 ] def",
  153.   "/ndays {\t\t% number of days in this month",
  154.   "\tdays_month month 1 sub get",
  155.   "\tmonth 2 eq\t% Feb",
  156.   "\tisleap and",
  157.   "\t{",
  158.   "\t\t1 add",
  159.   "\t} if",
  160.   "} def",
  161.   "/startday {\t\t% starting day-of-week for this month",
  162.   "\t/off year 2000 sub def\t% offset from start of epoch",
  163.   "\toff",
  164.   "\toff 4 idiv add\t\t% number of leap years",
  165.   "\toff 100 idiv sub\t% number of centuries",
  166.   "\toff 1000 idiv add\t% number of millenia",
  167.   "\t6 add 7 mod 7 add \t% offset from Jan 1 2000",
  168.   "\t/off exch def",
  169.   "\t1 1 month 1 sub {",
  170.   "\t\t/idx exch def",
  171.   "\t\tdays_month idx 1 sub get",
  172.   "\t\tidx 2 eq",
  173.   "\t\tisleap and",
  174.   "\t\t{",
  175.   "\t\t\t1 add",
  176.   "\t\t} if",
  177.   "\t\t/off exch off add def",
  178.   "\t} for",
  179.   "\toff 7 mod\t\t% 0--Sunday, 1--monday, etc.",
  180.   "} def",
  181.   "/center {\t\t% center string in given width",
  182.   "\t/width exch def",
  183.   "\t/str exch def width str ",
  184.   "\tstringwidth pop sub 2 div 0 rmoveto str show",
  185.   "} def",
  186.   "/calendar",
  187.   "{",
  188.   "\ttitlefont findfont 48 scalefont setfont",
  189.   "\t0 60 moveto",
  190.   "\t/month_name month_names month 1 sub get def",
  191.   "\tmonth_name show",
  192.   "\t/yearstring year 10 string cvs def",
  193.   "\t700 yearstring stringwidth pop sub 60 moveto",
  194.   "\tyearstring show",
  195.   "\t0 0 moveto",
  196.   "\tdrawnums",
  197.   "\t0 0 moveto",
  198.   "\tdrawfill",
  199.   "\t0 0 moveto",
  200.   "\tdrawgrid",
  201.   "} def",
  202.   "/daytext {",
  203.   "\t/Helvetica-Narrow findfont 6 scalefont setfont",
  204.   "\t/mytext\texch def /myday exch def",
  205.   "\tstartday myday 1 sub add dup 7 mod 100 mul 5 add % gives column",
  206.   "\texch 7 idiv -80 mul % gives row",
  207.   "\tdup /ypos exch def moveto",
  208.   "\t/LM currentpoint pop def /RM LM 95 add def",
  209.   "        mytext { dup (.p) eq { crlf pop} {prstr ( ) show} ifelse } forall",
  210.   "} def",
  211.   "/crlf {",
  212.   "    ypos 8 sub /ypos exch def LM ypos moveto",
  213.   "} def",
  214.   "/prstr {",
  215.   "    dup stringwidth pop currentpoint pop",
  216.   "    add RM gt {crlf 15 0 rmoveto} if show",
  217.   "} def",
  218.   "/printmonth {",
  219.   "\t90 rotate",
  220.   "\t50 -120 translate",
  221.   "\t/submonth 0 def",
  222.   "\tcalendar",
  223.   "\tmonth 1 sub 0 eq",
  224.   "\t{",
  225.   "\t\t/lmonth 12 def",
  226.   "\t\t/lyear year 1 sub def",
  227.   "\t}",
  228.   "\t{",
  229.   "\t\t/lmonth month 1 sub def",
  230.   "\t\t/lyear year def",
  231.   "\t} ifelse",
  232.   "\tmonth 1 add 13 eq",
  233.   "\t{",
  234.   "\t\t/nmonth 1 def",
  235.   "\t\t/nyear year 1 add def",
  236.   "\t} ",
  237.   "\t{",
  238.   "\t\t/nmonth month 1 add def",
  239.   "\t\t/nyear year def",
  240.   "\t} ifelse",
  241.   "\t/savemonth month def",
  242.   "\t/saveyear year def",
  243.   "\t/submonth 1 def",
  244.   "\t/year lyear def",
  245.   "\t/month lmonth def",
  246.   "\tgsave",
  247.   "\t500 -365 translate",
  248.   "\tgsave",
  249.   "\t.138 .138 scale",
  250.   "\t10 -120 translate",
  251.   "\tcalendar",
  252.   "\tgrestore",
  253.   "\t/submonth 1 def",
  254.   "\t/year nyear def",
  255.   "\t/month nmonth def",
  256.   "\t100 0 translate",
  257.   "\tgsave",
  258.   "\t.138 .138 scale",
  259.   "\t10 -120 translate",
  260.   "\tcalendar",
  261.   "\tgrestore",
  262.   "\t/month savemonth def",
  263.   "\t/year saveyear def",
  264.   "\t/submonth 0 def",
  265.   "\tgrestore",
  266.   "} def",
  267.   (char *)0,
  268. };
  269.  
  270. PrintPS::PrintPS(VCal *o)
  271. {
  272.   owner = o;
  273.  
  274.   printBox = NULL;
  275.   printFile = NULL;
  276. }
  277.  
  278. PrintPS::~PrintPS()
  279. {
  280. }
  281.  
  282. /**********************************************************************/
  283.  
  284. void
  285. PrintPS::printMonthUI(int month, int year)
  286. {
  287.   char tempFile[256], str[MAXSTR];
  288.   FILE *fd;
  289.  
  290.   if (printFile) {
  291.     theWarningDialog->post("Sorry, but a print dialog is still active");
  292.     return;
  293.   }
  294.   if (getenv("TMPDIR")) {
  295.     sprintf(tempFile, "%s/vcalPrint-XXXXXX", getenv("TMPDIR"));
  296.   } else {
  297.     sprintf(tempFile, "/tmp/vcalPrint-XXXXXX");
  298.   }
  299.   mktemp(tempFile);
  300.   if (fd = fopen(tempFile, "w")) {
  301.     printMonth(fd, month, year);
  302.     fclose(fd);
  303.     displayPrintUI(tempFile);
  304.   } else {
  305.     sprintf(str, "Couldn't create temporary file %s for printing", tempFile);
  306.     theWarningDialog->post(str);
  307.   }
  308. }
  309.  
  310. void
  311. PrintPS::printMonth(FILE *fd, int month, int year)
  312. {
  313.   int days, day, each;
  314.   MemoryInfo *dayInfo;
  315.   Entry *entry;
  316.   RepeatingEntry *rentry;
  317.   char str[MAXSTR];
  318.  
  319.   printHeader(fd);
  320.   fprintf(fd, "/year %d def\n", year);
  321.   fprintf(fd, "/month %d def\n", month);
  322.   fprintf(fd, "printmonth\n");
  323.  
  324.   days = NumberOfDays(month, year);
  325.   for (day=1; day<=days; day++) {
  326.     dayInfo = owner->findDateInfo(day, month, year);
  327.     owner->initCollect();
  328.     if (dayInfo) {
  329.       dayInfo->rewind();
  330.       while (entry = dayInfo->nextEntry()) {
  331.     owner->collectSingleEntry(entry);
  332.       }
  333.     }
  334.     rentry = owner->getRepeatingEntries();
  335.     while (rentry->next()) {
  336.       rentry = rentry->next();
  337.       if (rentry->repeatApplies(day, month, year)) {
  338.     owner->collectSingleEntry(rentry);
  339.       }
  340.     }
  341.     if (owner->collectedCount()) {
  342.       owner->sortCollection();
  343.       fprintf(fd, "%d [\n", day);
  344.       for (each=0; each<owner->collectedCount(); each++) {
  345.     entry = owner->collectedEntry(each);
  346.     formatTime(entry->start() / 60, entry->start() % 60,
  347.            thePreferences->clock24(),
  348.            str);
  349.     strcat(str, "-");
  350.     formatTime((entry->start()+entry->length()) / 60,
  351.            (entry->start()+entry->length()) % 60,
  352.            thePreferences->clock24(),
  353.            str+strlen(str));
  354.     strcat(str, " ");
  355.     strcat(str, entry->text());
  356.     emitWords(fd, str);
  357.     if (each < owner->collectedCount()-1) {
  358.       fprintf(fd, "(.p)\n");
  359.     }
  360.       }
  361.       fprintf(fd, "] daytext\n");
  362.     }
  363.   }
  364.  
  365.   fprintf(fd, "showpage\n");
  366. }
  367.  
  368. /**********************************************************************/
  369.  
  370. void
  371. PrintPS::printHeader(FILE *fd)
  372. {
  373.   const char **ap;
  374.  
  375.   for (ap=pheader; *ap; ap++) {
  376.     fputs(*ap, fd);
  377.     fputs("\n", fd);
  378.   }
  379. }
  380.  
  381. void
  382. PrintPS::emitWords(FILE *fd, char *str)
  383. {
  384.   char *dup, *p;
  385.  
  386.   dup = strdup(str);
  387.   if (p = strtok(dup, " \t")) {
  388.     fprintf(fd, "(%s)\n", p);
  389.     while (p = strtok(NULL, " \t\n")) {
  390.       fprintf(fd, "(%s)\n", p);
  391.     }
  392.   }
  393.   free(dup);
  394. }
  395.  
  396. void
  397. PrintPS::displayPrintUI(char *file)
  398. {
  399.   printFile = strdup(file);
  400.   count = 0;
  401.   XtSetArg(args[count], PuiNfilename, printFile);  count++;
  402.   if (printBox) {
  403.     XtSetValues(printBox, args, count);
  404.   } else {
  405.     printBox = PuiCreatePrintDialog(owner->baseWidget(), "printBox",
  406.                     args, count);
  407.     XtAddCallback(printBox, PuiNcancelCallback, cancel_cb, (XtPointer) this);
  408.     XtAddCallback(printBox, PuiNhelpCallback, help_cb, (XtPointer) this);
  409.     XtAddCallback(printBox, PuiNjobInfoCallback, print_cb, (XtPointer) this);
  410.     XtAddCallback(printBox, PuiNerrorCallback, error_cb, (XtPointer) this);
  411.     XtAddCallback(printBox, PuiNoptionErrorCallback, error_cb,
  412.           (XtPointer) this);
  413.   }
  414.   XtManageChild(printBox);
  415. }
  416.   
  417. void
  418. PrintPS::printComplete()
  419. {
  420.   if (printFile) {
  421.     unlink(printFile);
  422.     free(printFile);
  423.     printFile = NULL;
  424. /* Reuse the print box
  425.     XtDestroyWidget(printBox);
  426.     printBox = NULL;
  427. */
  428.   }
  429. }
  430.  
  431. /**********************************************************************/
  432.  
  433. void
  434. PrintPS::cancel_cb(Widget, XtPointer client_data, XtPointer)
  435. {
  436.   PrintPS *obj = (PrintPS *) client_data;
  437.  
  438.   obj->printComplete();
  439. }
  440.  
  441. void
  442. PrintPS::help_cb(Widget, XtPointer, XtPointer)
  443. {
  444.   SGIHelpMsg(NULL, NULL, NULL);
  445. }
  446.  
  447. void
  448. PrintPS::print_cb(Widget, XtPointer client_data, XtPointer call_data)
  449. {
  450.   PrintPS *obj = (PrintPS *) client_data;
  451.   PuiPrintBoxCallbackStruct *pb_cb = (PuiPrintBoxCallbackStruct*) call_data;
  452.   char str[256];
  453.  
  454.   sprintf(str, "request id is %s", pb_cb->job_info->job_id);
  455.   theWarningDialog->post(str);
  456.   obj->printComplete();
  457. }
  458.  
  459. void
  460. PrintPS::error_cb(Widget, XtPointer, XtPointer call_data)
  461. {
  462.   PuiPrintBoxCallbackStruct *pb_cb = (PuiPrintBoxCallbackStruct*) call_data;
  463.  
  464.   if (pb_cb->reason == PuiCR_OPT_ERROR) {
  465.     theWarningDialog->post(strerror(pb_cb->error_code));
  466.   } else {
  467.     theWarningDialog->post(SLErrorString(pb_cb->error_code));
  468.   }
  469. }
  470.  
  471.